package link;

import java.net.*;
import java.io.*;
import java.util.*;

public class PhysicalLayer {

	// The received message buffer. We use
	// an object in order to be shared between
	// server and clients on the same PhysicalLayer
	ReceivedBuffer rb;

	// The percentage of packets not dropped
	int successRate = 100;

	// Socket, port and group for broadcasting
	DatagramSocket client;

	int in_port, out_port;

	String server;

	public PhysicalLayer(String server) {
		try {
			rb = new ReceivedBuffer();
			client = new DatagramSocket();
			this.server = server;
			in_port = 11111;
			out_port = 11111;

			// here, we create and launch the listenning
			// server waiting for messages. When a message
			// is caught by the server, it is enqueue in
			// the received buffer.
			Thread t_s = new Thread(new Server(rb, in_port));
			t_s.start();
		} catch (IOException e) {
			System.out.println(e);
			System.exit(0); // kill program
		}
	}

	public PhysicalLayer(String server, int in, int out) {
		try {
			rb = new ReceivedBuffer();
			client = new DatagramSocket();
			this.server = server;
			in_port = in;
			out_port = out;

			// here, we create and launch the listenning
			// server waiting for messages. When a message
			// is caught by the server, it is enqueue in
			// the received buffer.
			Thread t_s = new Thread(new Server(rb, in_port));
			t_s.start();
		} catch (IOException e) {
			System.out.println(e);
			System.exit(0); // kill program
		}
	}

	public void setSuccessRate(int s) {

		// s must be between 0 and 100
		if ((s >= 0) && (s <= 100))
			successRate = s;
	}

	public void send(String message) {

		Random ran = new Random();

		// if a random number between 0 and 100 is
		// smaller than successRate, then we send the
		// message. Otherwise, we do nothing.
		if (ran.nextInt(100) <= successRate) {

			byte[] buf = message.getBytes();

			try {
				DatagramPacket pack = new DatagramPacket(buf, buf.length,
						InetAddress.getByName(server), out_port);

				client.send(pack);
			} catch (UnknownHostException e) {
				System.out.println(e);
				System.exit(0); // kill program
			} catch (IOException e) {
				System.out.println(e);
				System.exit(0); // kill program
			}
		}
	}

	public String receive() {
		return rb.receive();
	}

	public void addMessageInBuffer(String message) {
		rb.receiveBuffer.addFirst(message);
	}
}

